package com.mingqijia.gassafety.webserver.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.mingqijia.gassafety.authority.api.resp.config.DictionaryItemRespDTO;
import com.mingqijia.gassafety.authority.dal.helper.ConfigureHolder;
import com.mingqijia.gassafety.db.entity.Consumer;
import com.mingqijia.gassafety.db.entity.Dtu;
import com.mingqijia.gassafety.db.entity.WarningAlarm;
import com.mingqijia.gassafety.db.influxdb.config.InfluxDBConfiguration;
import com.mingqijia.gassafety.db.influxdb.config.InfluxDBConnect;
import com.mingqijia.gassafety.shared.constant.Constants;
import com.mingqijia.gassafety.shared.constant.EquipmentType;
import com.mingqijia.gassafety.shared.utils.ApplicationUtils;
import com.mingqijia.gassafety.shared.utils.commonUtils.PageUtil;
import com.mingqijia.gassafety.webserver.request.ConsumerListRequest;
import com.mingqijia.gassafety.webserver.request.LatestLogListRequest;
import com.mingqijia.gassafety.webserver.request.RecordLogRequest;
import com.mingqijia.gassafety.webserver.response.AlertLogResponse;
import com.mingqijia.gassafety.webserver.response.ConsumerResponse;
import com.mingqijia.gassafety.webserver.response.LatestLogListResponse;
import com.mingqijia.gassafety.webserver.response.WarningDataResponse;
import com.mingqijia.gassafety.webserver.service.*;
import lombok.extern.slf4j.Slf4j;
import org.influxdb.dto.QueryResult;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 报警记录 服务实现类
 * </p>
 *
 * @author guoliang.lao
 * @since 2022-03-04
 */
@Service
@Slf4j
public class AlertLogServiceImpl implements AlertLogService {

    @Autowired
    EquipmentService equipmentService;
    @Autowired
    InfluxDBConfiguration influxDBConfiguration;
    @Autowired
    ConsumerService consumerService;
    @Autowired
    ConfigureHolder holder;
    @Autowired
    DepartmentService departmentService;
    @Autowired
    CommonService commonService;

    @Override
    public PageUtil<AlertLogResponse> list(RecordLogRequest req) {
        List<AlertLogResponse> resultList = new ArrayList<>();
        String spId = req.getSpId();
        if (StringUtils.isEmpty(spId)) {
            spId = ApplicationUtils.getWorkingSpId();
        }
        //根据spId换path
        String path = "";
        if (spId==null&&!StringUtils.isEmpty(req.getPath())){
            path=req.getPath();
        }else {
            path= departmentService.getPath(spId);
        }
        //获取数据库连接
        InfluxDBConnect influxDBConnect = influxDBConfiguration.getInfluxDBConnect();
        List<Dtu> equipmentList = new ArrayList<>();
        if (!StringUtils.isEmpty(req.getImei()) || !StringUtils.isEmpty(req.getEquipmentName()) ||
                !StringUtils.isEmpty(req.getSubsCode()) || !StringUtils.isEmpty(req.getEquipmentType()) ||
                !StringUtils.isEmpty(req.getCustName()) || !StringUtils.isEmpty(req.getCustAddress()) ||
                !StringUtils.isEmpty(req.getCustPhone()) || !StringUtils.isEmpty(req.getIndustryType())) {
            LatestLogListRequest request = new LatestLogListRequest();
            request.setImei(req.getImei());
            request.setEquipmentName(req.getEquipmentName());
            request.setSubsCode(req.getSubsCode());
            request.setCustName(req.getCustName());
            request.setCustAddress(req.getCustAddress());
            request.setCustPhone(req.getCustPhone());
            request.setIndustryType(req.getIndustryType());
            if (req.getEquipmentType() == null || StringUtils.isEmpty(req.getEquipmentType())) {
                //查询全部
                request.setEquipmentTypes(new String[]{EquipmentType.INDEPENDENT_GAS_DETECTOR.getCode(),
                        EquipmentType.POINT_TYPE_GAS_DETECTOR.getCode(), EquipmentType.HOME_GAS_DETECTOR.getCode()});
            }else{
                request.setEquipmentTypes(new String[]{req.getEquipmentType()});
            }
            request.setSpId(spId);
            equipmentList = equipmentService.queryEquipmentList(request);
            if (equipmentList.isEmpty()) {
                return new PageUtil(req.getPage(), req.getPageSize(), 0, resultList);
            }
        }
        List<Map<String,String>> imeiList = equipmentList.stream().map(a->{
            Map<String,String> map = new HashMap();
            if (a.getEquipmentType().equals(EquipmentType.POINT_TYPE_GAS_DETECTOR.getCode())){
                map.put("imei",org.apache.commons.lang.StringUtils.substringBefore(a.getIMEI(), "-"));
                map.put("sub",org.apache.commons.lang.StringUtils.substringAfter(a.getIMEI(), "-"));
                return map;
            }else{
                map.put("imei",a.getIMEI());
                map.put("sub","1-1");
                return map;
            }
        }).collect(Collectors.toList());

        String where = "";
        String measurement = "select * from AlertLog where Path='"+path+"'";
        String measurementCount = "select count(ConsumerId) from AlertLog where Path='"+path+"'";
        if (!StringUtils.isEmpty(req.getTimeStart()) && !StringUtils.isEmpty(req.getTimeEnd())) {
            where = " and time>'"+req.getTimeStart() +"' and time<'"+req.getTimeEnd()+"'";
        }
        if (imeiList != null && !imeiList.isEmpty()) {
            StringBuffer dtuWhere = new StringBuffer();
            Map map = imeiList.get(0);
            dtuWhere.append(" and (DtuId='"+map.get("imei")+"'");
            for (int i = 1; i < imeiList.size(); i++) {
                Map map1 = imeiList.get(i);
                dtuWhere.append(" or DtuId='"+map1.get("imei")+"'");
            }
            dtuWhere.append(")");
            //sub参数拼接
            dtuWhere.append(" and (SubIdentifier='"+map.get("sub")+"'");
            for (int i = 1; i < imeiList.size(); i++) {
                Map map1 = imeiList.get(i);
                dtuWhere.append(" or SubIdentifier='"+map1.get("sub")+"'");
            }
            dtuWhere.append(")");
            where = where + dtuWhere;
        }
        String sort = " order by time desc limit "+ req.getPageSize() +" offset "+(req.getPage()-1)*req.getPageSize();
        //查询influxDb的AlertLog的总数
        String countSql = measurementCount + where;
        log.info(countSql);
        QueryResult countResult = influxDBConnect.query(countSql);

        Integer count = 0;
        if (countResult.getResults().get(0).getSeries() != null) {
            Double c = (Double) countResult.getResults().get(0).getSeries().get(0).getValues().get(0).get(1);
            count = c.intValue();
        }
        //分页查询influxDb的AlertLog
        String selectSql = measurement + where + sort;
        log.info(selectSql);
        QueryResult queryResult = influxDBConnect.query(selectSql);
        List<List<Object>> list = new ArrayList<>();
        if (queryResult.getResults().get(0).getSeries() != null) {
            list = queryResult.getResults().get(0).getSeries().get(0).getValues();
        }
        List<String> imeis = new ArrayList<>();
        for (List<Object> objects : list) {
            AlertLogResponse res = new AlertLogResponse();
            res.setImei(objects.get(4).toString());
            res.setSubId(objects.get(8).toString());
            res.setLatestTime(DateUtil.parse(objects.get(0).toString()));
            JSONObject json = JSONUtil.parseObj(objects.get(6));
            if (!StringUtils.isEmpty(json.getStr("value"))) {
                res.setXlel(json.getStr("value") + " " + json.getStr("unit"));
            }
            res.setConsumerId(Double.valueOf(objects.get(1).toString()).intValue());
            res.setId(DateUtil.parse(objects.get(0).toString()).getTime()*1000000);

            Double dtuType = Double.valueOf(objects.get(5).toString());
            if (Constants.DTU_TYPE_CONTROLLER.equals(dtuType.intValue())) {
                imeis.add(res.getImei()+"-"+res.getSubId());
            } else {
                imeis.add(res.getImei());
            }
            resultList.add(res);
        }
        if (!imeis.isEmpty()){
            LambdaQueryWrapper<Dtu> queryWrapper = new LambdaQueryWrapper();
            queryWrapper.in(Dtu::getIMEI,imeis).eq(Dtu::getSpId,spId);
            if (req.getEquipmentType() == null || StringUtils.isEmpty(req.getEquipmentType())) {
                //查询全部
                queryWrapper.in(Dtu::getEquipmentType, new String[]{EquipmentType.INDEPENDENT_GAS_DETECTOR.getCode(),
                        EquipmentType.POINT_TYPE_GAS_DETECTOR.getCode(), EquipmentType.HOME_GAS_DETECTOR.getCode()});
            } else {
                queryWrapper.eq(Dtu::getEquipmentType,req.getEquipmentType());
            }
            List<Dtu> dtuList = equipmentService.list(queryWrapper);

            for (AlertLogResponse res : resultList) {
                for (Dtu dtu : dtuList) {
                    if (dtu.getIMEI().equals(res.getImei()) || dtu.getIMEI().equals(res.getImei()+"-"+res.getSubId())) {
                        BeanUtils.copyProperties(dtu,res);
                        res.setImei(dtu.getIMEI());
                        DictionaryItemRespDTO dict = holder.getDictionaryByKey(
                                EquipmentType.DICT_CODE).stream().filter(a->a.getValue().equals(
                                res.getEquipmentType())).collect(Collectors.toList()).get(0);
                        res.setEquipmentTypeName(dict.getName());
                        res.setEquipmentName(dtu.getName());
                    }
                }
                //客户信息
                List<Integer> consumerIds = resultList.stream().map(AlertLogResponse::getConsumerId).collect(Collectors.toList());
                LambdaQueryWrapper<Consumer> consumerQueryWrapper = new LambdaQueryWrapper<>();
                consumerQueryWrapper.eq(Consumer::getSpId,spId).in(Consumer::getId,consumerIds);
                List<Consumer> consumerList = consumerService.list(consumerQueryWrapper);
                for (Consumer consumer : consumerList) {
                    if (res.getConsumerId().equals(consumer.getId())) {
                        res.setSubsCode(consumer.getSubsCode());
                        res.setIndustryType(consumer.getIndustryType());
                        res.setCustName(consumer.getCustName());
                        res.setCustAddress(consumer.getCustAddress());
                        res.setCustPhone(consumer.getCustPhone());
                        //行业类型
                        if (!StringUtils.isEmpty(res.getIndustryType())) {
                            DictionaryItemRespDTO communicationModeDict = holder.getDictionaryByKey(
                                    Constants.INDUSTRY_TYPE_CODE).stream().filter(a->a.getValue().equals(
                                    res.getIndustryType())).collect(Collectors.toList()).get(0);
                            res.setIndustryType(communicationModeDict.getName());
                        }
                    }
                }
            }
        }

        PageUtil pageInfo = new PageUtil(req.getPage(), req.getPageSize(), count, resultList);
        return pageInfo;
    }
}
